#include "timer.h"
#define error (0);
#define ok (1);

uint8_t Set_System_clock(uint32_t clock_signal, uint32_t clock_source,
                         uint32_t divider) {
  WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;
  CS->KEY = CLOCK_KEY;
  switch (clock_signal) {
    case ACLK:
      if (clock_source != LFXT && clock_source != REFO && clock_source != VLO)
        return error;
      CS->CTL1 =
          ((divider >> ACLK_DIV_BITPOS) | (clock_source << ACLK_SRC_BITPOS)) |
          (CS->CTL1 & ~(CTL1_SELA_MASK | CTL1_DIVA_MASK));
      break;
    case MCLK:
      CS->CTL1 =
          ((divider >> MCLK_DIV_BITPOS) | (clock_source << MCLK_SRC_BITPOS)) |
          (CS->CTL1 & ~(CTL1_SELA_MASK | CTL1_DIVA_MASK));
      break;
    case SMCLK:
      CS->CTL1 = ((divider >> SMCLK_DIV_BITPOS) |
                  (clock_source << HSMCLK_SRC_BITPOS)) |
                 (CS->CTL1 & ~(CTL1_DIVS_MASK | CS_CTL1_SELS_MASK));
      break;
    case HSMCLK:
      CS->CTL1 = ((divider >> HSMCLK_DIV_BITPOS) |
                  (clock_source << HSMCLK_SRC_BITPOS)) |
                 (CS->CTL1 & ~(CTL1_DIVHS_MASK | CTL1_SELS_MASK));
      break;
    case BCLK:
      if (clock_source == LFXT)
        BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS) = 0;
      else if (clock_source == REFO)
        BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS) = 1;
      else
        return error;
  }
  BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
  return ok;
}

uint8_t Set_DCO_Freq(uint32_t freq) {
  if (freq != DCO_FREQUENCY_1_5 && freq != DCO_FREQUENCY_3 &&
      freq != DCO_FREQUENCY_6 && freq != DCO_FREQUENCY_12 &&
      freq != DCO_FREQUENCY_24 && freq != DCO_FREQUENCY_48)
    return error;
  CS->KEY = CLOCK_KEY;
  CS->CTL0 = ((CS->CTL0 & ~CTL0_DCORSEL_MASK) | freq);
  BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
}
